#pragma once
#pragma warning(disable:4996)       // disable checked iterator errors http://msdn.microsoft.com/en-us/library/aa985965(VS.80).aspx 

//
// Copyright (C) 2011 - 2013 Steve Channell steve.channell@cepheis.com
//
// This file is part of Cephei.QL, an open-source library wrapper 
// arround QuantLib http://quantlib.org/
//
// Cephei.QL is open source software: you can redistribute it and/or modify it
// under the terms of the license.  You should have received a
// copy of the license along with this program; if not, please email
// <support@cepheis.com>. The license is also available online at
// <http://cepheis.com/license.htm>.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the license for more details.
//
// Version 2.2 with QuantLib 1.2.1

#include <Macros.h>
#include <ValueHelpers.h>
#include <Settings.h>

#include <gen/QL/StochasticProcess1D.h>
#pragma unmanaged 
#include <ql\experimental\processes\gemanroncoroniprocess.hpp>
#include <boost/smart_ptr/detail/spinlock.hpp>
#pragma managed 

using namespace System;
using namespace QuantLib;
using namespace Cephei;
using namespace Cephei::Core;
using namespace PLATFORM::Collections;

using namespace Cephei::QL::Math;
using namespace Cephei::QL;
#define HANDLE
#undef ABSTRACT
#undef STRUCT
namespace Cephei { namespace QL { namespace Experimental { namespace Processes {
	//////////////////////////////////////////////////////////////////////////////////////////////
	// implementation of IGemanRoncoroniProcess
	public ref class CGemanRoncoroniProcess  : 
            public CStochasticProcess1D,
            public Cephei::QL::Experimental::Processes::IGemanRoncoroniProcess
	{
	protected: 
		boost::shared_ptr<QuantLib::GemanRoncoroniProcess>* _ppGemanRoncoroniProcess;
#ifdef HANDLE
		QuantLib::Handle<QuantLib::GemanRoncoroniProcess>* _phGemanRoncoroniProcess;
#endif
		Object^ _GemanRoncoroniProcessOwner;     // reference to object that manages the storage for this object
	internal:
		CGemanRoncoroniProcess (Double x0, Double alpha, Double beta, Double gamma, Double delta, Double eps, Double zeta, Double d, Double k, Double tau, Double sig2, Double a, Double b, Double theta1, Double theta2, Double theta3, Double psi);
        CGemanRoncoroniProcess (boost::shared_ptr<QuantLib::GemanRoncoroniProcess>& childNative, Object^ owner);
        CGemanRoncoroniProcess (QuantLib::GemanRoncoroniProcess& childNative, Object^ owner);
        CGemanRoncoroniProcess (CGemanRoncoroniProcess^ copy);
        CGemanRoncoroniProcess (PLATFORM::Type^ t);
#ifdef STRUCT
        CGemanRoncoroniProcess (QuantLib::GemanRoncoroniProcess childNative);
#endif       
#ifdef HANDLE
		CGemanRoncoroniProcess (QuantLib::Handle<QuantLib::GemanRoncoroniProcess>& childNative, Object^ owner);
		CGemanRoncoroniProcess (QuantLib::Handle<QuantLib::GemanRoncoroniProcess> childNative);
#endif
		virtual ~CGemanRoncoroniProcess ();
		!CGemanRoncoroniProcess ();

	internal:
		QuantLib::GemanRoncoroniProcess& GetReference ();
		boost::shared_ptr<QuantLib::GemanRoncoroniProcess>& GetShared ();
		QuantLib::GemanRoncoroniProcess* GetPointer ();
        void SetGemanRoncoroniProcess (boost::shared_ptr<QuantLib::GemanRoncoroniProcess> native)
        {
            if (_ppGemanRoncoroniProcess != NULL)
                delete _ppGemanRoncoroniProcess;
            _ppGemanRoncoroniProcess = new boost::shared_ptr<QuantLib::GemanRoncoroniProcess> (native);
            SetStochasticProcess1D (boost::dynamic_pointer_cast<QuantLib::StochasticProcess1D> (*_ppGemanRoncoroniProcess));
        }
#ifdef HANDLE
		QuantLib::Handle<QuantLib::GemanRoncoroniProcess>& GetHandle ();
#endif
		virtual bool HasNative () override;
    public:
		virtual Double Diffusion (Double t, Double x) ;
		virtual Double Drift (Double t, Double x) ;
		virtual Double Evolve (Double t0, Double x0, Double dt, Double dw, Cephei::QL::Math::IArray^ du) ;
		virtual Double Evolve (Double t0, Double x0, Double dt, Double dw) ;
		virtual Double StdDeviation (Double t0, Double x0, Double dt) ;
        property Double X0 
        {
		    virtual Double get () ;
        }
    };
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Factory class
//z	[FactoryFor(Core::Generic::ICoCell<Cephei::QL::Experimental::Processes::IGemanRoncoroniProcess^>::typeid)]
	[FactoryFor(Cephei::QL::Experimental::Processes::IGemanRoncoroniProcess::typeid)]
	[FactoryFor(Cephei::QL::Experimental::Processes::IGemanRoncoroniProcess_Factory::typeid)]
	public ref class CGemanRoncoroniProcess_Factory sealed : public IGemanRoncoroniProcess_Factory
	{
	public:
        virtual IGemanRoncoroniProcess^ Create (Double x0, Double alpha, Double beta, Double gamma, Double delta, Double eps, Double zeta, Double d, Double k, Double tau, Double sig2, Double a, Double b, Double theta1, Double theta2, Double theta3, Double psi);
    };
   
/*Cephei*/ } /*QL*/ } /*Experimental*/ } /*Processes */}
